
import * as ol from '../openLayer'
import {getRadius} from '../../handle'
import { Draw, Modify, DoubleClickZoom } from 'ol/interaction.js'
import { WKT, GeoJSON, TopoJSON } from 'ol/format'
// import WKT from 'ol/format/WKT.js'
// import TopoJSON from 'ol/format/TopoJSON.js'
import { getArea, getLength } from 'ol/sphere.js'
import { LineString, Point, MultiPolygon, Polygon,Circle } from 'ol/geom.js'
import { fromCircle } from 'ol/geom/Polygon'
import { drawDefaultConfig, drawShapArr, dataType } from './config'
import OlMessage from '../Message'
import { drawingLineStyle, drawEndLineStyle, pointTipStyle, setLabelStyle, setTipStyle, modifyStyle } from './style'
import { deepAssign } from '@/utils/tools/deepAssign'
import * as turf from '@turf/turf'
import {Style} from 'ol/style.js';
/**
 * 绘制图形shap 类，
 * 配置项参考config.js
 * 样式项参考style.js
 */
export default class OlDrawShap {
  constructor (_map, _config) {
    this.map = _map
    this.options = deepAssign(drawDefaultConfig, _config) //  配置项
    this.draw = null
    this.source = null
    this.mouseTipModify = null //  鼠标提示modify
    this.mouseTip = null //  鼠标提示文字
    // this.onUpdateOlDrawShap = this.updateOlDrawShap(_map, _config)
    /** 禁止原有的双加放大地图事件 */
    let doubleClickZoom = new DoubleClickZoom()
    let doubleClickZoomArr = this.map.getInteractions().array_.filter(
      item => {
        return item.constructor.name === doubleClickZoom.constructor.name
      }
    )
    this.map.removeInteraction(doubleClickZoomArr[0])
      this.circleFeatures=[]
    /** 禁止原有的双加放大地图事件 */
    this.distoryDraw()
   
    this.onBackfillData()
    if(!this.options.shapConfig.onlyShow){ //仅仅展示
      
      this.onDrawShap()
    }

   
    
  }

  /**
   * 更新配置
   */
  updateOlDrawShap (_map, _config) {
    // console.log('更新',  _config)
    this.map = _map
    this.distoryDraw()
    this.options = deepAssign(drawDefaultConfig, _config) //  配置项

    if(!this.options.shapConfig.onlyShow){ //仅仅展示
      this.onDrawShap()
    }else{
     
      this.onBackfillData()
    }
  }

  /**
   * 注销draw
   */
  distoryDraw () {
    console.log('draw', this.draw)
    if (this.draw) {
      this.draw.finishDrawing()
      this.map.removeInteraction(this.draw)
      this.draw.setActive(false)
      this.draw = null
    }
  }

  /**
   * 数据初始化
   */
  onBackfillData () {
  
    let features
    let tempsPolygon, firstPoint
    if (this.options?.shapConfig?.data) { //  回填数据
      if (dataType.indexOf(this.options.shapConfig.dataType) > -1) {
        let dataArr = this.options?.shapConfig?.data||[]
        switch (this.options.shapConfig.dataType) {
          case 'wkt':
            if(this.options.shapConfig.type==='CustomCircle'){ // 用户自定义圆形
              if(dataArr.length>0){
                for(let item of dataArr){
                  let style = item?.style || this.options?.lineConfig?.drawEndStyle
                  let circleFeature = new WKT().readFeatures(item)
                  circleFeature.setStyle(
                    new Style({
                      fill:  new ol.Fill({
                        color: style.fillColor,
                      }),
                      stroke: new ol.Stroke({
                        color: style.strokeColor
                      })
                    }),
                  );
                  this.circleFeatures.push(circleFeature)
                }
                features = this.circleFeatures;
              }
            }else{
              features = [new WKT().readFeature(this.options.shapConfig.data)]
            }
            
            break
          case 'geoJSON':
            if(this.options.shapConfig.type==='CustomCircle'){ // 用户自定义圆形
              let dataArr = this.options?.shapConfig?.data||[]
              if(dataArr.length>0){
                for(let item of dataArr){
                  let style = item?.style || this.options?.lineConfig?.drawEndStyle
                  let circleFeature = new GeoJSON().readFeatures(item)
                  circleFeature.setStyle(
                    new Style({
                      fill:  new ol.Fill({
                        color: style.fillColor,
                      }),
                      stroke: new ol.Stroke({
                        color: style.strokeColor
                      })
                    }),
                  );
                  this.circleFeatures.push(circleFeature)
                }
                features = this.circleFeatures;
              } 
            }else{
              features = new GeoJSON().readFeatures(this.options.shapConfig.data)
            }
            

            break
          case 'corrdinates':
            // console.log(this.options.shapConfig.data, new MultiPolygon(this.options.shapConfig.data))
            if(this.options.shapConfig.type==='CustomCircle'){ //自定义圆形，用户只需要传递经纬度（lng,lat）和半径(radius)
             let dataArr = this.options?.shapConfig?.data||[]
              if(dataArr.length>0){
              if(this.circleFeatures.length>0){
                for(let i in dataArr){
                  let center = [dataArr[i]?.lng,  dataArr[i].lat]
                  let radius = getRadius(this.map,dataArr[i]?.radius,dataArr[i]?.units)
                  this.circleFeatures[i].getGeometry().setCenterAndRadius(center,radius)
                }
              }else{
                for(let item of dataArr){
                  let center = [item?.lng,  item.lat]
                  let radius = getRadius(this.map,item?.radius,item?.units)
                  let style = item?.style || this.options?.lineConfig?.drawEndStyle
                  let circleFeature = new ol.Feature({
                    geometry:new Circle(center,radius)
                  })
                  circleFeature.setStyle(
                    new Style({
                      fill:  new ol.Fill({
                        color: style.fillColor,
                      }),
                      stroke: new ol.Stroke({
                        color: style.strokeColor
                      })
                    }),
                  );
                  this.circleFeatures.push(circleFeature)
                }
                features = this.circleFeatures;
              }
            }
              
            }else{ // 默认使用openlayer 自带的多边形进行数据回填
              tempsPolygon = new MultiPolygon(this.options.shapConfig.data) //  多维 polygon
              firstPoint = tempsPolygon.getFirstCoordinate()
              if (firstPoint.length === 0) {
                tempsPolygon = new Polygon(this.options.shapConfig.data)
                firstPoint = tempsPolygon.getFirstCoordinate()
              }
              // console.log('firstPoint',firstPoint)
              features = [new ol.Feature({
                geometry: tempsPolygon
              })]
            }
            
            break
        }
      } else {
        // console.log('类型错误')
        // alert('类型错误')
        let message = new OlMessage({
          message: '类型错误',
          type: 'error'
        })
      }
    }
    if (features) {
      this.source = new ol.VectorSource({
        features: features
      })
    } else {
      this.source = new ol.VectorSource()
    }
    let drawLayer
    if(this.options.shapConfig.type!=='CustomCircle'){
      drawLayer= new ol.VectorLayer({
        source: this.source,
        className: 'DrawShapLayer',
        properties: this.options.layerProperties,
        style: (feature) => {
         
          return this.getDrawStyle(feature, this.options.shapConfig.type, true)
        }
      })
    }else{
      drawLayer= new ol.VectorLayer({
        source: this.source,
        className: 'DrawShapLayer',
        properties: this.options.layerProperties
      })
    }
    
    // console.log('drawLayer=', drawLayer)
    this.map.addLayer(drawLayer)

    this.mouseTipModify = new Modify({ source: this.source, style: this.modifyStyle })
    this.mouseTip = this.options.mouseTipConfig.tipText
  }

  /**
   * 初始化绘制
   */
  onDrawShap () {
    console.log('this.options', this.options.shapConfig)
    if (drawShapArr.indexOf(this.options.shapConfig.type) > -1||this.options.shapConfig.type==='CustomCircle') {
      if(drawShapArr.indexOf(this.options.shapConfig.type) > -1){
        this.handleDraw()
      }else{

      }
      
    } else {
      // console.log('类型错误')
      // alert('类型错误')
      let message = new OlMessage({
        message: '类型错误1',
        type: 'error'
      })
    }
  }
  /**
 * 获取线段长度
 * @param {*} line
 * @returns
 */
  formatLength (line) {
    const length = getLength(line)
    let output
    if (length > 100) {
      output = Math.round((length / 1000) * 100) / 100 + ' km'
    } else {
      output = Math.round(length * 100) / 100 + ' m'
    }
    return output
  };



  /**
   * 获取当前绘制样式
   */
  getDrawStyle (feature, drawType = 'MultiPolygon', drawEndBool = false, tip) {
    let styles
    if (drawEndBool) {
      styles = [drawEndLineStyle(this.options)]
    } else {
      styles = [drawingLineStyle(this.options)]
    }
    const geometry = feature.getGeometry()
    const type = geometry.getType()
    let point, label, line, lines
    // if (drawEndBool) {
    //   console.log('type', type, geometry)
    // }
    //
    if (this.options.labelConfig.show) { // 显示点位提示
      if ((type === 'Polygon' || type === 'MultiPolygon')) { // 多边形求面积
        if (type === 'Polygon') {
          point = geometry.getInteriorPoint()
        } else if (type === 'MultiPolygon') {
          point = geometry.getInteriorPoints()
        }
        // console.log('point=', point)
        line = new LineString(geometry.getCoordinates()[0])
        label = this.formatArea(geometry)
      } else if (type === 'LineString' || type === 'MultiLineString') { //  线条算距离
        point = new Point(geometry.getLastCoordinate())

        label = this.formatLength(geometry)
        line = geometry
      } else if (type === 'Circle') {
        let radius = geometry.getRadius() * 1000
        label = Math.round(Math.PI * radius * radius) + ' km\xB2'
        point = new Point(geometry.getCenter())
      }
      if (line) {
        let count = 0
        const pointTipStyles = [pointTipStyle(this.options, drawEndBool)]
        if (type === 'MultiLineString') { //  线
          lines = geometry.getLineStrings()
          for (let i in lines) {
            // console.log('i=', i)
            lines[i].forEachSegment((a, b) => {
              const segment = new LineString([a, b])
              const label = this.formatLength(segment)
              if (pointTipStyles.length - 1 < count) {
                pointTipStyles.push(pointTipStyle(this.options, drawEndBool).clone())
              }
              const segmentPoint = new Point(segment.getCoordinateAt(0.5))
              pointTipStyles[count].setGeometry(segmentPoint)
              pointTipStyles[count].getText().setText(label)
              styles.push(pointTipStyles[count])
              count++
            })
          }
          // if (drawEndBool) {
          //   console.log('point=', point, 'lines=', lines)
          // }
        } else if (type === 'MultiPolygon' || type === 'Polygon') { //  多边形
          line.forEachSegment((a, b) => {
            const segment = new LineString([a, b])
            const label = this.formatLength(segment)
            if (pointTipStyles.length - 1 < count) {
              pointTipStyles.push(pointTipStyle(this.options, drawEndBool).clone())
            }
            const segmentPoint = new Point(segment.getCoordinateAt(0.5))
            pointTipStyles[count].setGeometry(segmentPoint)
            pointTipStyles[count].getText().setText(label)
            styles.push(pointTipStyles[count])
            count++
          })
        }
      }
      if (label) {
        const labelStyle = setLabelStyle(this.options, drawEndBool)
        labelStyle.setGeometry(point)
        labelStyle.getText().setText(label)
        styles.push(labelStyle)
      }
    }
    if (this.options.mouseTipConfig.show) { // 鼠标提示
      let tipPoint
      const tipStyle = setTipStyle(this.options)
      if (tip && type === 'Point' && !this.mouseTipModify.getOverlay().getSource().getFeatures().length) {
        tipPoint = geometry
        tipStyle.getText().setText(tip)
        styles.push(tipStyle)
      }
    }
    // console.log('styles=', styles)
    return styles
  }

  /**
   * 绘制
   */
  handleDraw () {
    if (!this.draw) {
      this.draw = new Draw({
        source: this.source,
        type: this.options.shapConfig.type,
        geometryName: this.options.layerProperties.id,
        style: (feature) => {
          // console.log('样式', this.getDrawStyle(feature, 'LineString', '测试'))
          return this.getDrawStyle(feature, this.options.shapConfig.type, false, this.mouseTip)
        }
      })

      this.draw.setActive(true)
      

      this.draw.on('drawstart', () => {
        if (!this.options.shapConfig.isMultipleBool && this.source) {
          this.source.clear()
        }
        this.mouseTipModify.setActive(false)
        this.mouseTip = this.options.mouseTipConfig.drawTipText
      })
      this.draw.on('drawend', (e) => {
        if (this.options.callBackConfig.show) { // 将图形信息返回给调用者
          let geometry = e.feature.getGeometry() // 获取几何体的geometry
          let corrdinates = geometry.getCoordinates()// 获取几何体的点位
          const type = geometry.getType() // 获取几何体的类型
          let wkt, topoJSON, geoJSON, center, radius
          // console.log('type=', type, corrdinates)
          if (type === 'MultiLineString') {
            corrdinates[0].push(corrdinates[0][0])
            console.log('corrdinates', corrdinates)
            geometry = new Polygon(corrdinates)
            geoJSON = new GeoJSON().writeGeometry(geometry)
          } else if (type === 'Circle') {
            // console.log(corrdinates)
            geometry = fromCircle(geometry)
            geoJSON = new GeoJSON().writeGeometry(geometry)
            let coordinates = JSON.parse(geoJSON).coordinates
            let polygon = turf.polygon(coordinates)
            // 中心点
            center = turf.centerOfMass(polygon).geometry.coordinates
            // console.log(center)
            let firstCoords = geometry.flatCoordinates
            let from = turf.point([firstCoords[0], firstCoords[1]])
            let to = turf.point(center)
            let options = { units: 'kilometers' }
            radius = turf.distance(from, to, options) * 1000
          }
          wkt = new WKT().writeGeometry(geometry)
          // console.log(center, radius)
          // console.log('draw end,geometry', geometry, wkt, geoJSON)
          // console.log('this.options.callBackConfig?.handle', this.options.callBackConfig?.handle)
          if (this.options.callBackConfig?.handle) {
            this.options.callBackConfig?.handle({ geometry, center, radius, corrdinates, wkt, type, geoJSON })
          }
        }
        this.mouseTip = this.options.mouseTipConfig.tipText
        if (this.draw && !this.options.shapConfig.isMultipleBool) { // 多图绘制
          this.draw.finishDrawing()
          e.stopPropagation()
          e.preventDefault()
          this.map.removeInteraction(this.draw)
          this.draw.setActive(false)
          this.draw = null
        }
      })
      this.mouseTipModify.setActive(true)
      this.map.addInteraction(this.draw)
    }
  }
}
